package com.dwf.dominion;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.dwf.dominion.Card.Type;


public class CardsXMLParser implements Runnable {
	private enum InputFileType {
		INPUT_STREAM, FILE, UNKNOWN
	};
	
	private Vector<Card> cards = new Vector<Card>(0);
	private String lastError;
	
	private DocumentBuilder dBuilder = null;
	private Document doc = null;
	private Handler handler = null;
	private int what = 0;
	
	private InputStream stream;
	private File file;
	private InputFileType type = InputFileType.UNKNOWN;
	
	public CardsXMLParser() {
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		try {
			dBuilder = dbFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public CardsXMLParser(Handler handler, int what) {
		this();
		this.handler = handler;
		this.what = what;
	}

	public void ParseThreaded(File file) {
		this.file = file;
		type = InputFileType.FILE;
		new Thread(this).start();
	}
	
	public void ParseThreaded(InputStream stream) {
		this.stream = stream;
		type = InputFileType.INPUT_STREAM;
		new Thread(this).start();		
	}
	
	public void Parse(File file) {		
		cards.removeAllElements();
		
		try {
			doc = dBuilder.parse(file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		ParseMain();
	}
	
	public void Parse(InputStream stream) {
		cards.removeAllElements();
	}
	
	public String GetLastError() {
		return lastError;
	}
	
	public Vector<Card> GetResults() {
		return cards;
	}
	
	private void ParseMain() {
		NodeList sets = doc.getElementsByTagName("sets");
		
		//For every device
		for(int i=0;i<sets.getLength();i++) {
			//Note node
			
			Node set = sets.item(i);
			
			NodeList name = ((Element) set).getElementsByTagName("name");
			NodeList cardsList = ((Element) set).getElementsByTagName("card");
			
			
			for(int j=0; j < cardsList.getLength(); j++) {
				//Card card = new Card();
				
				Node card = cardsList.item(j);
				NodeList card_name = ((Element) card).getElementsByTagName("name");
				NodeList type = ((Element) card).getElementsByTagName("type");
				NodeList coin_cost = ((Element) card).getElementsByTagName("coin_cost");
				NodeList potion_cost = ((Element) card).getElementsByTagName("potion_cost");
				NodeList conditional_cost = ((Element) card).getElementsByTagName("conditional_cost");
				NodeList plus_coins = ((Element) card).getElementsByTagName("plus_coins");
				NodeList plus_actions = ((Element) card).getElementsByTagName("plus_actions");
				NodeList plus_buys = ((Element) card).getElementsByTagName("plus_buys");
				NodeList plus_cards = ((Element) card).getElementsByTagName("plus_cards");
				NodeList trash_cards = ((Element) card).getElementsByTagName("trash_cards");
				NodeList given_curses = ((Element) card).getElementsByTagName("given_curses");
				
				String set_name_val = name.item(0).getFirstChild().getNodeValue();
				String card_name_val = card_name.item(0).getFirstChild().getNodeValue();
				int coin_cost_val = Integer.parseInt(coin_cost.item(0).getFirstChild().getNodeValue());
				
				int potion_cost_val = 0;
				int plus_coins_val = 0;
				int plus_actions_val = 0;
				int plus_buys_val = 0;
				int plus_cards_val = 0;
				int trash_cards_val = 0;
				int given_curses_val = 0;
				
				if(potion_cost.getLength() > 0) {
					potion_cost_val = Integer.parseInt(potion_cost.item(0).getFirstChild().getNodeValue());
				}
				
				if(plus_coins.getLength() > 0) {
					plus_coins_val = Integer.parseInt(plus_coins.item(0).getFirstChild().getNodeValue());
				}
				
				if(plus_actions.getLength() > 0) {
					plus_actions_val = Integer.parseInt(plus_actions.item(0).getFirstChild().getNodeValue());
				}
				
				if(plus_buys.getLength() > 0) {
					plus_buys_val = Integer.parseInt(plus_buys.item(0).getFirstChild().getNodeValue());
				}
				
				if(plus_cards.getLength() > 0) {
					plus_cards_val = Integer.parseInt(plus_cards.item(0).getFirstChild().getNodeValue());
				}
				
				if(trash_cards.getLength() > 0) {
					trash_cards_val = Integer.parseInt(trash_cards.item(0).getFirstChild().getNodeValue());
				}
				
				if(given_curses.getLength() > 0) {
					given_curses_val = Integer.parseInt(given_curses.item(0).getFirstChild().getNodeValue());
				}
				
//				ArrayList<Card.Type> test_type;
//				
//				Object[] dummy = Card.Type.values();
//				
//				for(Object o: dummy) {
//					Log.i("that",o.toString());
//					
//				}
				
				//public Card(String name, int cost, boolean potion, Set set, Type[] types, int buys, int coins, int actions, int cards)
				Card toAdd = new Card	(	card_name_val,
											coin_cost_val,
											(potion_cost_val==0)?false:true,
											Card.Set.Dominion,					//TODO: hard coded
											new Type[]{Card.Type.ACTION},		//TODO: hard coded
											plus_buys_val,
											plus_coins_val,
											plus_actions_val,
											plus_cards_val
										);
				
//				if(make.getLength() > 0) {
//					Node item = make.item(0).getFirstChild();
//					info.setMake(item.getNodeValue());
//				}
//				
//				if(model.getLength() > 0) {
//					Node item = model.item(0).getFirstChild();
//					info.setModel(item.getNodeValue());
//				}
//				
//				if(major.getLength() > 0) {
//					Node item = major.item(0).getFirstChild();
//					info.setMajorVersion(Integer.parseInt(item.getNodeValue()));
//				}
//				
//				if(minor.getLength() > 0) {
//					Node item = minor.item(0).getFirstChild();
//					info.setMinorVersion(Integer.parseInt(item.getNodeValue()));
//				}
//				
//				if(dot.getLength() > 0) {
//					Node item = dot.item(0).getFirstChild();
//					info.setDotVersion(Integer.parseInt(item.getNodeValue()));
//				}
//				
//				if(major.getLength() > 0) {
//					Node item = url.item(0).getFirstChild();
//					info.setURL(item.getNodeValue());
//				}
				
//				cards.add(info);
			} //per version loop
		} //per device loop
	} //ParseMain function

	public void run() {
		switch(type) {
		case INPUT_STREAM:
			this.Parse(stream);
			break;
		case FILE:
			this.Parse(file);
			break;
		default:
			break;
		}
		
		if(handler != null) {
			try {
				Message XMLResults = Message.obtain(handler, what);
				XMLResults.obj = this;
				handler.sendMessage(XMLResults);
			} catch (Exception e) {Log.e("XMLParser",e.toString()); }
		}
	}
} //cardsXMLParser class
